<template>
    <div>
        <div @click="catchInputEvent">
            <el-input
                class="select-input"
                style="width:100%;"
                v-model="labelValue"
                :clearable="labelValue!=null"
                :readonly="readonly"
                :placeholder="$t('common.pla.pleaseSelect')"
                @blur="handleBlur"
                @clear="handleClear"
                @keyup.native="handleChange"
                ref="input"
            >
                <i
                    slot="suffix"
                    class="el-input__icon el-icon-arrow-up"
                    :class="{'is-reverse': visible}"
                ></i>
            </el-input>
        </div>
        <div v-if="visible" class="list" @click="catchEvent">
            <ul v-if="showData.length!=0">
                <li
                    v-for="(item,index) in showData"
                    :key="index"
                    @click="handleSelect(item)"
                    :class="value==item.value?'current-item':null"
                >{{item.label}}</li>
            </ul>
            <el-row class="page-btns" v-if="showPage">
                <el-col :span="6">
                    <el-button type="text" v-if="pageIndex!=0" @click="pageFirst">首页</el-button>
                    <span v-else>首页</span>
                </el-col>
                <el-col :span="6">
                    <el-button type="text" v-if="pageIndex!=0" @click="pagePrev">上一页</el-button>
                    <span v-else>上一页</span>
                </el-col>
                <el-col :span="6">
                    <el-button
                        type="text"
                        v-if="pageCount!=0&&pageIndex<pageCount-1"
                        @click="pageNext"
                    >下一页</el-button>
                    <span v-else>下一页</span>
                </el-col>
                <el-col :span="6">
                    <el-button
                        type="text"
                        v-if="pageCount!=0&&pageIndex<pageCount-1"
                        @click="pageLast"
                    >末页</el-button>
                    <span v-else>末页</span>
                </el-col>
            </el-row>
        </div>
    </div>
</template>
<script>
export default {
    name: "PageSelect",
    props: {
        source: {
            required: true
        },
        pageSize: {
            default: 10
        },
        value: {},
        readonly: {
            default: false
        }
    },
    data() {
        return {
            labelValue: null,
            visible: false,
            sourceData: null,
            showData: null,
            indexAttr: Symbol(),
            showPage: false,
            pageIndex: 0,
            pageCount: 0,
            clearTimeoutId: null
        };
    },
    mounted() {
        if (this.source instanceof Array) {
            this.source.forEach(v => {
                if (v.label != null) {
                    v.label = v.label.replace(/(^\s*)|(\s*$)/g, "");
                }
            });
            this.sourceData = _.cloneDeep(this.source);
            this.initPage();
            if (this.value != null) {
                let option = this.sourceData.find(s => s.value == this.value);
                if (option) {
                    this.labelValue = option.label;
                }
            }
        }
    },
    methods: {
        createDataIndex() {
            this.sourceData.forEach((v, index) => {
                v[this.indexAttr] = index;
            });
        },
        pageFirst() {
            this.pageIndex = 0;
            this.showData = this.sourceData.filter(
                v => v[this.indexAttr] < this.pageSize
            );
        },
        pageLast() {
            this.pageIndex = this.pageCount - 1;
            this.showData = this.sourceData.filter(
                v =>
                    v[this.indexAttr] < this.pageCount * this.pageSize &&
                    v[this.indexAttr] >= (this.pageCount - 1) * this.pageSize
            );
        },
        pageNext() {
            this.pageIndex++;
            this.showData = this.sourceData.filter(
                v =>
                    v[this.indexAttr] < (this.pageIndex + 1) * this.pageSize &&
                    v[this.indexAttr] >= this.pageIndex * this.pageSize
            );
        },
        pagePrev() {
            this.pageIndex--;
            this.showData = this.sourceData.filter(
                v =>
                    v[this.indexAttr] < (this.pageIndex + 1) * this.pageSize &&
                    v[this.indexAttr] >= this.pageIndex * this.pageSize
            );
        },
        handleBlur() {
            if (this.clearTimeoutId) {
                clearTimeout(this.clearTimeoutId);
            }
            this.clearTimeoutId = setTimeout(() => {
                this.visible = false;
                if (this.value == null) {
                    this.labelValue = null;
                } else {
                    let v = this.source.find(v => v.value == this.value);
                    if (v) {
                        this.labelValue = v.label;
                    } else {
                        this.labelValue = null;
                    }
                }
                if (this.sourceData.length != this.source.length) {
                    this.sourceData = _.cloneDeep(this.source);
                    this.initPage();
                }
            }, 150);
        },
        handleSelect(item) {
            this.labelValue = item.label;
            this.$emit("input", item.value);
            this.visible = !this.visible;
            if (this.sourceData.length != this.source.length) {
                this.sourceData = _.cloneDeep(this.source);
                this.initPage();
            }
        },
        initPage() {
            this.createDataIndex();
            this.pageIndex = 0;
            if (this.sourceData.length == 0 || this.pageSize == 0) {
                this.pageCount = 0;
            } else {
                if (this.sourceData.length % this.pageSize == 0) {
                    this.pageCount = this.sourceData.length / this.pageSize;
                } else {
                    this.pageCount = this.sourceData.length / this.pageSize + 1;
                }
            }
            if (this.sourceData.length <= this.pageSize) {
                this.showPage = false;
                this.showData = this.sourceData;
            } else {
                this.showPage = true;
                this.showData = this.sourceData.filter(
                    v => v[this.indexAttr] < this.pageSize
                );
            }
        },
        handleClear() {
            this.$emit("input", null);
            this.sourceData = _.cloneDeep(this.source);
            this.initPage();
        },
        handleChange() {
            this.sourceData = _.cloneDeep(
                this.source.filter(v => v.label.indexOf(this.labelValue) >= 0)
            );
            this.initPage();
        },
        catchInputEvent(event) {
            if (
                event.target.nodeName == "input" ||
                event.target.nodeName == "INPUT"
            ) {
                this.visible = true;
            } else {
                this.visible = false;
            }
        },
        catchEvent(e) {
            let stop = false;
            if (
                e.target.nodeName != "UL" &&
                e.target.nodeName != "ul" &&
                e.target.nodeName != "LI" &&
                e.target.nodeName != "li"
            ) {
                stop = true;
            }
            if (stop && this.clearTimeoutId) {
                clearTimeout(this.clearTimeoutId);
                this.$refs.input.focus();
                this.clearTimeoutId = null;
            }
        }
    }
};
</script>
<style lang="scss" scoped>
.el-input__icon.el-icon-arrow-up {
    -webkit-transition: -webkit-transform 0.3s;
    transition: -webkit-transform 0.3s;
    transition: transform 0.3s;
    transition: transform 0.3s, -webkit-transform 0.3s;
    transition: transform 0.3s, -webkit-transform 0.3s;
    -webkit-transform: rotateZ(180deg);
    transform: rotateZ(180deg);
    &.is-reverse {
        -webkit-transform: rotateZ(0);
        transform: rotateZ(0);
    }
}
.list {
    width: 100%;
    position: absolute;
    z-index: 1;
    background: #fff;
    ul {
        margin: 0;
        padding: 5px;
    }
    ul li {
        margin: 0;
        list-style-type: none;
        font-size: 14px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        color: #606266;
        height: 34px;
        line-height: 34px;
        cursor: pointer;
    }
    ul li:hover {
        color: #3a7fe8;
        background: #ebf2ff;
    }
    ul li.current-item {
        color: #3a7fe8;
        background: #ebf2ff;
    }
    .page-btns {
        text-align: center;
    }
}
</style>